package com.homwee.serialportinspection.serialport;

import android.bluetooth.BluetoothDevice;
import android.net.wifi.ScanResult;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.os.Bundle;

import com.homwee.serialportinspection.model.Command;
import com.homwee.serialportinspection.model.Types;

import java.util.List;

public class VinsmartCommand implements Command {
    private static final String TAG = "VinsmartCommand";
    private static final String END_CHAR = "\r";

    /**************** keys. ******************/
    private static final String KEY_VOL_UP = "VOLUME UP";
    private static final String KEY_VOL_DOWN = "VOLUME DOWN";
    private static final String KEY_CHANNEL_UP = "CHANNEL UP";
    private static final String KEY_CHANNEL_DOWN = "CHANNEL DOWN";
    private static final String KEY_INPUT = "INPUT";
    private static final String KEY_MENU = "MENU";
    private static final String KEY_POWER = "POWER";

    /**************** command. ***************/
    private static final String CMD_POWER = "POWR";
    private static final String CMD_STANDBY = "STBY";
    private static final String CMD_SOURCE = "IAVD";
    private static final String CMD_ATV_CHANNEL = "DCCH";
    private static final String CMD_DTV_CHANNEL = "DTVD";
    private static final String CMD_VOLUME = "VOLM";
    private static final String CMD_SPDIF_MODE = "DAUD";
    private static final String CMD_PICTURE_MODE = "CVMD";
    private static final String CMD_M_MODE = "KRSW";
    private static final String CMD_F_MODE_ENABLE = "KKT1"; /* factory mode enable */
    private static final String CMD_FACTORY_MENU = "FACT";
    private static final String CMD_FACTORY_INSPECTION = "GKMD";
    private static final String CMD_FACTORY_INIT = "INIT";
    private static final String CMD_BACKLIGHT = "SBSL";
    private static final String CMD_TACT_CHECK = "TASW";
    private static final String CMD_SW_VERSION = "VERS";
    private static final String CMD_WB_ADJUST = "MSET";
    private static final String CMD_WB_R = "WB4R";  // user setting color temp
    private static final String CMD_WB_G = "WB4G";
    private static final String CMD_WB_B = "WB4B";
    private static final String CMD_FACTORY_WB_PREFIX = "MG";
    private static final String CMD_FACTORY_WB_PATTERN = "WBPT";
    private static final String CMD_CT_MODE = "CTMP";
    private static final String CMD_WB_MAX = "CHGM";
    private static final String CMD_LCD_PATTERN_DISPLAY = "LCTP";
    private static final String CMD_SND_CHN_MODE = "SSBL";
    private static final String CMD_MUTE = "SSPO";
    private static final String CMD_USB_STORAGE_CNT = "USBT";
    private static final String CMD_ETH_MAC = "WMAC";
    private static final String CMD_WIFI = "WIFI";
    private static final String CMD_BT = "BLTO";
    private static final String CMD_ETH_IP = "RDIP";
    private static final String CMD_EMMC_ID = "ECID";
    private static final String CMD_SET_SN = "WSEN";
    private static final String CMD_GET_SN = "RSEN";
    private static final String CMD_GET_STATUS = "GETS";

    /************** response. **************/
    private static final String RESPONSE_OK = "OK";
    private static final String RESPONSE_ERR = "ERR";
    private static final String KEYCHECK_ON = "KEYCHECK ON";
    private static final String KEYCHECK_OFF = "KEYCHECK OFF";

    /************** param. *************/
    private static final String PARAM_0000 = "0000";
    private static final String PARAM_0001 = "0001";
    private static final String PARAM_INQUIRE = "????";
    private static final String PARAM_FACTORY_INIT = "0006";
    private static final String PARAM_WB_ADJUST_EXIT = "0003";
    private static final String PARAM_WB_MAX_BEFORE = "0255";
    private static final String PARAM_WB_MAX_AFTER = "1255";
    private static final String PARAM_PATTERN_OFF = "0007";
    private static final String PARAM_ETH_MAC_WRITE = "0001";
    private static final String PARAM_ETH_MAC_READ = "0002";
    private static final String PARAM_BT_MAC = "0001";
    private static final String PARAM_BT_AP_PREFIX = "02";
    private static final String PARAM_BT_SCAN_CMP = "0003";
    private static final String PARAM_COLORTEMP_INQUIRE = "000?";
    private static final String PARAM_WIFI_AP_SSID_PREFIX = "11";
    private static final String PARAM_WIFI_THRESHOLD_RSSI_PREFIX = "3";
    private static final String PARAM_WIFI_SCAN = "5101";
    private static final String PARAM_WIFI_CMP_RSSI = "6100";
    private static final String PARAM_ENABLE_F_MODE = "0037";
    private static final String PARAM_GETCOMPILETIME = "0001";
    private static final String PARAM_GETPROJECTID = "0002";
    private static final String PARAM_GETPANELSEL = "0003";
    private static final String PARAM_GETPQVER = "0004";
    private static final String PARAM_GETAQVER = "0005";
    private static final String PARAM_GETHDCPKEY14 = "0006";
    private static final String PARAM_GETHDCPKEY22 = "0007";
    private static final String PARAM_GETWIDEVINEKEY = "0008";
    private static final String PARAM_GETKEYMASTER = "0009";
    private static final String PARAM_GETPLAYREADY = "0010";
    private static final String PARAM_GETPLAYREADY25 = "0011";
    private static final String PARAM_GETPANELVERSION = "0012";
    private static final String PARAM_GETDATAVERSION = "0013";

    /*************** types. ****************/
    private static final int SOURCE_HDMI1 = 1;
    private static final int SOURCE_HDMI2 = 2;
    private static final int SOURCE_HDMI3 = 3;
    private static final int SOURCE_HDMI4 = 4;
    private static final int SOURCE_DTV = 5;
    private static final int SOURCE_ATV = 6;
    private static final int SOURCE_AV = 7;

    private static final int SPDIF_MODE_OFF = 0;
    private static final int SPDIF_MODE_RAW = 1;
    private static final int SPDIF_MODE_PCM = 2;

    private static final int PICTURE_MODE_USER = 1;
    private static final int PICTURE_MODE_STANDARD = 2;
    private static final int PICTURE_MODE_VIVID = 3;
    private static final int PICTURE_MODE_SPORT = 4;
    private static final int PICTURE_MODE_MOVIE = 5;
    private static final int PICTURE_MODE_GAME = 6;
    private static final int PICTURE_MODE_ENERGYSAVE = 7;

    private static final int CT_MODE_NORMAL = 1;
    private static final int CT_MODE_COOL = 2;
    private static final int CT_MODE_WARM = 3;
    private static final int CT_MODE_USER = 4;

    private static final int WIFI_START_RESULT_BUSY = -2;

    private static final int COMMAND_FIELD = 3;
    private static final int PARAMETER_FIELD = 5;

    private static boolean mEthernetWMode = false;
    private static int mFactoryMode = Types.FactoryMode.STATE_INIT.ordinal();

    // wifi
    private static final String VS_AP_SSID_PREFIX = "Af";

    // bt
    private static final String VS_BT_AP_PREFIX = "VSM_BT_";

    private boolean mIsKeyCheckOn = false;


    private String mApSsid = "";
    private int mThresholdRssi = 0;


    private String mBtAp = "";

    @Override
    public Message toRequest(String command) {
        Log.d(TAG, "toRequest get cmd "+command);
        Message request = Message.obtain();

		/*
        if (command == null || command.length() == 0) {
            request.what = Types.INVALID;
            return request;
        }

        if (mIsKeyCheckOn && !command.equals(CMD_TACT_CHECK + PARAM_0001)) {
            setSendKeyRequest(command, request);
            return request;
        }
        */
        String cmd = "";
        String param = "";
       /*
        if (Integer.toHexString((int) command.charAt(0)).equals(1)
            && command.length() == 1) {
            request.what = Types.INVALID;
            return request;
        }
       */
        try {
            cmd = command.substring(0, COMMAND_FIELD);
            param = command.substring(COMMAND_FIELD, PARAMETER_FIELD);
        } catch (RuntimeException e) {
            e.printStackTrace();
            request.what = Types.INVALID;
            return request;
        }

		/*
        //It's not factory working mode
        if (setEnterFactoryMode(param, request, command)) {
            Log.d(TAG, "Handle Factory Mode Command!");
            return request;
        }
        */
        if (cmd.startsWith(CMD_FACTORY_WB_PREFIX)) {
            setFactoryWbRequest(cmd, param, request);
            return request;
        }

        switch (cmd) {
            case CMD_POWER:
                setPowerRequest(param, request);
                break;

            case CMD_STANDBY:
                setStandbyRequest(param, request);
                break;

            case CMD_SOURCE:
                setSourceRequest(param, request);
                break;

            case CMD_ATV_CHANNEL:
                setChannelRequest(true, param, request);
                break;

            case CMD_DTV_CHANNEL:
                setChannelRequest(false, param, request);
                break;

            case CMD_VOLUME:
                setVolumeRequest(param, request);
                break;

            case CMD_SPDIF_MODE:
                setSpdifModeRequest(param, request);
                break;

            case CMD_PICTURE_MODE:
                setPictureMode(param, request);
                break;

            case CMD_FACTORY_INSPECTION:
                setFactoryInspectionMode(param, request);
                break;

            case CMD_FACTORY_INIT:
                setFactoryInit(param, request);
                break;

            case CMD_BACKLIGHT:
                setBacklight(param, request);
                break;

            case CMD_TACT_CHECK:
                setTactSwTest(param, request);
                break;

            case CMD_SW_VERSION:
                getSwVersion(param, request);
                break;

            case CMD_WB_ADJUST:
                setWbAdjust(param, request);
                break;

            case CMD_WB_R:
                setWbAdjR(param, request);
                break;

            case CMD_WB_G:
                setWbAdjG(param, request);
                break;

            case CMD_WB_B:
                setWbAdjB(param, request);
                break;

            case CMD_CT_MODE:
                setColorTempMode(param, request);
                break;

            case CMD_WB_MAX:
                showWbPatternMax(param, request);
                break;

            case CMD_LCD_PATTERN_DISPLAY:
                setLcdPatternDisplay(param, request);
                break;

            case CMD_FACTORY_WB_PATTERN:
                factoryWbPattern(param, request);
                break;

            case CMD_SND_CHN_MODE:
                SoundBalanceTest(param, request);
                break;

            case CMD_MUTE:
                SpeakerTest(param, request);
                break;

            case CMD_USB_STORAGE_CNT:
                getUsbCount(param, request);
                break;

            case CMD_ETH_MAC:
                ethernetMacAddress(param, request, command);
                break;

            case CMD_WIFI:
                wifiSettings(param, request);
                break;

            case CMD_BT:
                bluetoothSettings(param, request);
                break;

            case CMD_ETH_IP:
                getEthernetIP(param, request);
                break;

            case CMD_EMMC_ID:
                Log.d(TAG, "[" + CMD_EMMC_ID + "] Not support!");
                break;

            case CMD_SET_SN:
                Log.d(TAG, "[" + CMD_SET_SN + "] Not support!");
                break;

            case CMD_GET_SN:
                getSN(param, request);
                break;

            case CMD_GET_STATUS:
                getStatus(param, request);
                break;

             default:
                request.what = Types.INVALID;
                Log.e(TAG, "unkown support cmd = " + cmd);
        }

        if (request.what == Types.INVALID) {
            Log.e(TAG, "invalid command = " + command);
        }

        return request;
    }


    @Override
    //public byte[] toRequest(byte[] command) {
    public Message  toRequest(byte[] command) {
        Log.d(TAG, "toRequest get cmd "+command);
        Message request = Message.obtain();

        //if (command == null || command.length == 0 || command[0] != 0x36 || command[1] != 0x96) {
        //    request.what = Types.INVALID;
	    //byte[] ret = {command[0],(byte)0x86,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00};
        //    return ret;
       // }
/*
        if (mIsKeyCheckOn && !command.equals(CMD_TACT_CHECK + PARAM_0001)) {
            setSendKeyRequest(command, request);
            return request;
        }
*/
		/*
        String cmd = "";
        String param = "";
        if (Integer.toHexString((int) command.charAt(0)).equals(1)
            && command.length() == 1) {
            request.what = Types.INVALID;
            return request;
        }
		*/
		if(command[0] != (byte)(0x36) || command[1] != (byte)(0x96)){
            Log.d(TAG, "toRequest command error cmd0 "+command[0]+" cmd1 "+command[1]);
            request.what = Types.INVALID;
			return request;

		}
        byte inputSum = 0;
	    for(int i = 0; i < command.length -1; i++){
			inputSum = (byte)((byte)inputSum+(byte)command[i]);
			Log.d(TAG, " sum "+inputSum+" command ["+i+"] "+command[i]);
		}
		if(command[command.length -1] != (inputSum & (byte)0xFF)){
			Log.d(TAG, "toRequest chsum error sum "+inputSum+" command "+command[command.length -1]);
			request.what = Types.INVALID;
			return request;
		}
		/*
		if(MtkSerialPort.DEBUG_TYPE == 0){

			if(command[5] != ((byte)(command[0]+(byte)command[1]+(byte)command[2]+(byte)command[3]+(byte)command[4]) & (byte)0xFF)){
				Log.d(TAG, "toRequest chsum error c 5"+command[5]);
				request.what = Types.INVALID;
				return request;
			}
		} else {

			if(command[9] != ((byte)(command[0]+(byte)command[1]+(byte)command[2]+(byte)command[3]+(byte)command[4] +(byte)command[5] +(byte)command[6]+(byte)command[7]+(byte)command[8]) & (byte)0xFF)){
				Log.d(TAG, "toRequest chsum error c 9"+command[10]);
				request.what = Types.INVALID;
				return request;
			}
		}
        */
		switch(command[2]){
            case (byte)0x80:
				request.what = Types.Request_CH.WB_CONNECT.ordinal();
				return request;
            case (byte)0x81:
				request.what = Types.Request_CH.WB_PREPARE.ordinal();
				request.arg1 = (int)command[3];
				request.arg2 = (int)command[5];
				return request;
            case (byte)0x82:
				request.what = Types.Request_CH.WB_COLORTEMP_OPTION.ordinal();
				request.arg1 = (int)command[5];
				return request;
			case (byte)0x83:
				request.what = Types.Request_CH.WB_PICTUR_MODE_OPTION.ordinal();
				request.arg1 = (int)command[5];
				return request;
			case (byte)0x84:
				request.what = Types.Request_CH.WB_OSD_BACKLIGHT_MAX.ordinal();
				request.arg1 = (int)command[5];
				return request;
			case (byte)0x85:
				request.what = Types.Request_CH.WB_OSD_BACKLIGHT_MIN.ordinal();
				request.arg1 = (int)command[5];
				return request;
			case (byte)0x89:
				request.what = Types.Request_CH.WB_R_GAIN_SET.ordinal();
				request.arg1 = (int)command[3];
				request.arg2 = (int)command[4];
				return request;
			case (byte)0x8A:
				request.what = Types.Request_CH.WB_G_GAIN_SET.ordinal();
				request.arg1 = (int)command[5];
				request.arg2 = (int)command[6];
				return request;
			case (byte)0x8B:
				request.what = Types.Request_CH.WB_B_GAIN_SET.ordinal();
				request.arg1 = (int)command[7];
				request.arg2 = (int)command[8];
				return request;
			case (byte)0x8F:
			case (byte)0x90:
			case (byte)0x91:
				if(command[2] == (byte)0x8F){
				    request.what = Types.Request_CH.WB_STAND_SAVE.ordinal();
				}else if(command[2] == (byte)0x90){
				    request.what = Types.Request_CH.WB_WARM_SAVE.ordinal();
				} else {
				    request.what = Types.Request_CH.WB_COOL_SAVE.ordinal();
				}
                Bundle bundle = new Bundle();
				bundle.putInt("Rhigh",(int)command[3]);
				bundle.putInt("Rlow",(int)command[4]);
				bundle.putInt("Ghigh",(int)command[5]);
				bundle.putInt("Glow",(int)command[6]);
				bundle.putInt("Bhigh",(int)command[7]);
				bundle.putInt("Blow",(int)command[8]);
				request.setData(bundle);
				
				return request;
				
			case (byte)0x92:
				request.what = Types.Request_CH.WB_R_GAIN_GET.ordinal();
				return request;
			case (byte)0x93:
				request.what = Types.Request_CH.WB_G_GAIN_GET.ordinal();
				return request;
			case (byte)0x94:
				request.what = Types.Request_CH.WB_B_GAIN_GET.ordinal();
				return request;
			//serial port 	
			case (byte)0x00:
				request.what = Types.Request_CH.CONNECT.ordinal();
				return request;
			case (byte)0x10:
				request.what = Types.Request_CH.ARC_CEC_OPT.ordinal();
				request.arg1 = (int)command[3];
				return request;
			case (byte)0x11:
				request.what = Types.Request_CH.KPORT_OFF.ordinal();
				request.arg1 = (int)command[3];
				return request;
			case (byte)0x12:
				request.what = Types.Request_CH.GET_KEYCODE.ordinal();
				//request.arg1 = (int)command[3];
				return request;
			case (byte)0x13:
				request.what = Types.Request_CH.KPORT_ON.ordinal();
				request.arg1 = (int)command[3];
				return request;
			case (byte)0x20:
				request.what = Types.Request_CH.GET_LAN_IP.ordinal();
				request.arg1 = (int)command[3];
				return request;
			case (byte)0x21:
				request.what = Types.Request_CH.WIFI_SCAN.ordinal();
				return request;
			case (byte)0x22:
				request.what = Types.Request_CH.PRESET_CHANNEL.ordinal();
				request.arg1 = (int)command[3];
				return request;
			case (byte)0x23:
				request.what = Types.Request_CH.BT_SCAN.ordinal();
				return request;
			case (byte)0x2A:
				request.what = Types.Request_CH.GET_VER_INFO.ordinal();
				request.arg1 = (int)command[3];
				return request;
			case (byte)0x30:
				request.what = Types.Request_CH.KEY_STATUS_CHECK.ordinal();
				return request;


		}
//		request.what = Types.Request
        /*
        try {
            cmd = command.substring(0, COMMAND_FIELD);
            param = command.substring(COMMAND_FIELD, PARAMETER_FIELD);
        } catch (RuntimeException e) {
            e.printStackTrace();
            request.what = Types.INVALID;
            return request;
        }

        //It's not factory working mode
        if (setEnterFactoryMode(param, request, command)) {
            Log.d(TAG, "Handle Factory Mode Command!");
            return request;
        }

        if (cmd.startsWith(CMD_FACTORY_WB_PREFIX)) {
            setFactoryWbRequest(cmd, param, request);
            return request;
        }

        switch (cmd) {
            case CMD_POWER:
                setPowerRequest(param, request);
                break;

            case CMD_STANDBY:
                setStandbyRequest(param, request);
                break;

            case CMD_SOURCE:
                setSourceRequest(param, request);
                break;

            case CMD_ATV_CHANNEL:
                setChannelRequest(true, param, request);
                break;

            case CMD_DTV_CHANNEL:
                setChannelRequest(false, param, request);
                break;

            case CMD_VOLUME:
                setVolumeRequest(param, request);
                break;

            case CMD_SPDIF_MODE:
                setSpdifModeRequest(param, request);
                break;

            case CMD_PICTURE_MODE:
                setPictureMode(param, request);
                break;

            case CMD_FACTORY_INSPECTION:
                setFactoryInspectionMode(param, request);
                break;

            case CMD_FACTORY_INIT:
                setFactoryInit(param, request);
                break;

            case CMD_BACKLIGHT:
                setBacklight(param, request);
                break;

            case CMD_TACT_CHECK:
                setTactSwTest(param, request);
                break;

            case CMD_SW_VERSION:
                getSwVersion(param, request);
                break;

            case CMD_WB_ADJUST:
                setWbAdjust(param, request);
                break;

            case CMD_WB_R:
                setWbAdjR(param, request);
                break;

            case CMD_WB_G:
                setWbAdjG(param, request);
                break;

            case CMD_WB_B:
                setWbAdjB(param, request);
                break;

            case CMD_CT_MODE:
                setColorTempMode(param, request);
                break;

            case CMD_WB_MAX:
                showWbPatternMax(param, request);
                break;

            case CMD_LCD_PATTERN_DISPLAY:
                setLcdPatternDisplay(param, request);
                break;

            case CMD_FACTORY_WB_PATTERN:
                factoryWbPattern(param, request);
                break;

            case CMD_SND_CHN_MODE:
                SoundBalanceTest(param, request);
                break;

            case CMD_MUTE:
                SpeakerTest(param, request);
                break;

            case CMD_USB_STORAGE_CNT:
                getUsbCount(param, request);
                break;

            case CMD_ETH_MAC:
                ethernetMacAddress(param, request, command);
                break;

            case CMD_WIFI:
                wifiSettings(param, request);
                break;

            case CMD_BT:
                bluetoothSettings(param, request);
                break;

            case CMD_ETH_IP:
                getEthernetIP(param, request);
                break;

            case CMD_EMMC_ID:
                Log.d(TAG, "[" + CMD_EMMC_ID + "] Not support!");
                break;

            case CMD_SET_SN:
                Log.d(TAG, "[" + CMD_SET_SN + "] Not support!");
                break;

            case CMD_GET_SN:
                getSN(param, request);
                break;

            case CMD_GET_STATUS:
                getStatus(param, request);
                break;

             default:
                request.what = Types.INVALID;
                Log.e(TAG, "unkown support cmd = " + cmd);
        }
        */

        if (request.what == Types.INVALID) {
            Log.e(TAG, "invalid command = " + command);
        }

        return null;
    }

    @Override
    public String toCommand(Message response) {
        if (response.what == Types.INVALID) {
            return RESPONSE_ERR;
        }

        String command = "";
//        Types.Request reqType = Types.Request.values()[response.what];
        Types.Request_CH reqType = Types.Request_CH.values()[response.what];

        switch (reqType) {
			/*
            case POWER_OFF:
            case STANDBY:
            case SET_SOURCE:
            case SET_CHANNEL:
            case SET_VOLUME:
            case SET_SPDIF_MODE:
            case SET_PICTURE_MODE:
            case ENTER_FACTORY_MODE:
            case EXIT_FACTORY_MODE:
            case ENTER_FACTORY_MENU:
            case EXIT_FACTORY_MENU:
            case FACTORY_INIT:
            case SET_BACKLIGHT:
            case RESET_WB:
            case SET_WB_PART:
            case SET_CT_MODE:
            case SHOW_PATTERN:
            case CLOSE_PATTERN:
            case SET_SOUND_MODE:
            case SET_MUTE:
            case SET_ETH_MAC:
            case ENABLE_WIFI:
            case DISABLE_WIFI:
            case SEND_KEY:
            case SHOW_WB_BEFORE:
            case SHOW_WB_AFTER:
            case EXIT_WB:
            case SET_SOUND_BALANCE:
            case FACTORY_SET_WB:
            case FACTORY_WB_PATTERN:
                if (response.arg1 == Types.RESPONSE_OK) {
                    command = RESPONSE_OK;
                } else if (response.arg1 == Types.RESPONSE_ERR) {
                    command = RESPONSE_ERR;
                } else {
                    Log.e(TAG, reqType + " invalid arg1 = " + response.arg1);
                }
                break;

            case GET_WIFI_SCANRESULT:
                command = fromWifiScanResult((List<ScanResult>) response.obj);
                break;

            case GET_SOURCE:
                command = fromInputSource(response.arg1);
                break;

            case GET_CHANNEL:
                command = (response.arg2 == Types.INVALID) ? RESPONSE_ERR : String.valueOf(response.arg2);
                break;

            case GET_VOLUME:
            case GET_BACKLIGHT:
            case GET_WB_PART:
            case FACTORY_GET_WB:
            case GET_USB_STORAGE_CNT:
            case GET_SOUND_BALANCE:
                command = (response.arg1 == Types.INVALID) ? RESPONSE_ERR : String.valueOf(response.arg1);
                break;

            case GET_SPDIF_MODE:
                command = fromSpdifMode(response.arg1);
                break;
	
            case GET_PICTURE_MODE:
                command = fromPictureMode(response.arg1);
                break;

            case GET_SW_VERSION:
            case GET_ETH_IP:
            case GET_BT_VERSION:
            case GET_SERIAL_NUMBER:
                String result = (String) response.obj;
                command = TextUtils.isEmpty(result) ? RESPONSE_ERR : result;
                break;

            case GET_ETH_MAC:
            case GET_WIFI_MAC:
            case GET_BT_MAC:
                String mac = (String) response.obj;
                command = TextUtils.isEmpty(mac) ? RESPONSE_ERR : mac.replace(":", ""); // VS mac without ":"
                break;

            case START_BT_DISCOVERY:
                command = (response.arg1 == Types.RESPONSE_OK) ? "" : RESPONSE_ERR;   // NOTE: DON'T response immediately, will callback to response
                return command; // NOTE: direct return to forbid add END_CHAR

            case GET_BT_DISCOVERIED_DEV:
                command = fromBtDevice((BluetoothDevice) response.obj);
                break;
	
            case GET_CT_MODE:
                command = fromColorTempMode(response.arg1);
                break;
	
            case GET_MUTE:
                command = (response.arg1 != 0) ? "OFF" : "ON";  // on off mean speaker, not mute
                break;

            case START_WIFI_SCAN:
                if (response.arg1 == WIFI_START_RESULT_BUSY) {
                    command = "BUSY";
                } else if (response.arg1 == Types.RESPONSE_OK) {
                    command = RESPONSE_OK;
                } else {
                    command = RESPONSE_ERR;
                }
                break;

            case GET_BT_CONNECTED_DEV:
                command = ((String[]) response.obj).toString();
                break;

            case GET_COMPILE_TIME:
                String compileTime = (String) response.obj;
                command = TextUtils.isEmpty(compileTime) ? RESPONSE_ERR : compileTime;
                break;
            case GET_PROJECT_ID:
            case GET_PANEL_NAME:
                String writeString = (String) response.obj;
                command = TextUtils.isEmpty(writeString) ? RESPONSE_ERR : writeString;
                break;
            case GET_AQ_VERSION:
                String aqVersion = (String) response.obj;
                command = TextUtils.isEmpty(aqVersion) ? RESPONSE_ERR : aqVersion;
                break;
            case GET_PQ_VERSION:
                String pqVersion = (String) response.obj;
                command = TextUtils.isEmpty(pqVersion) ? RESPONSE_ERR : pqVersion;
                break;
            case GET_PANEL_VERSION:
                String panelVerion = (String) response.obj;
                command = TextUtils.isEmpty(panelVerion) ? RESPONSE_ERR : panelVerion;
                break;
            case GET_DATA_VERSION:
                String dataVersion = (String) response.obj;
                command = TextUtils.isEmpty(dataVersion) ? RESPONSE_ERR : dataVersion;
                break;
            case GET_HDCP_1_4:
            case GET_HDCP_2_2:
            case GET_WIDEVINE_STATUS:
            case GET_KEYMASTER_STATUS:
            case GET_PLAYREADY_STATUS:
            case GET_PLAYREADY_2_5_STATUS:
                command = ((boolean)response.obj == true) ? RESPONSE_OK : RESPONSE_ERR;
                break;
				*/
		    case WB_CONNECT:
                command = ((boolean)response.obj == true) ? RESPONSE_OK : RESPONSE_ERR;
				break;
            default:
                Log.e(TAG, "unkown respons type = " + reqType);
                command = RESPONSE_ERR;
                break;
        }

        return command + END_CHAR;
    }
    @Override
    public byte[] toCommand_CH(Message response) {
		byte[] error_replay = new byte[7] ;
		error_replay[0] = (byte)0x36;
		error_replay[1] = (byte)0x86;
		error_replay[2] = (byte)0x80;
		error_replay[3] = (byte)0x00;
		error_replay[4] = (byte)0x00;
		error_replay[5] = (byte)0x00;
		error_replay[6] = (byte)0x0d;
		//error_replay[7] = (byte)0x0a;
        if (response.what == Types.INVALID || response.what == Types.RESPONSE_ERR) {
            //return RESPONSE_ERR;
                Log.e(TAG, "unkown respons type = " + response.what);
            return error_replay;
        }

        byte[] reply = new byte[7];
//        Types.Request reqType = Types.Request.values()[response.what];
        Types.Request_CH reqType = Types.Request_CH.values()[response.what];
        Log.e(TAG, "reqType  " + reqType);


        switch (reqType) {
			/*
            case POWER_OFF:
            case STANDBY:
            case SET_SOURCE:
            case SET_CHANNEL:
            case SET_VOLUME:
            case SET_SPDIF_MODE:
            case SET_PICTURE_MODE:
            case ENTER_FACTORY_MODE:
            case EXIT_FACTORY_MODE:
            case ENTER_FACTORY_MENU:
            case EXIT_FACTORY_MENU:
            case FACTORY_INIT:
            case SET_BACKLIGHT:
            case RESET_WB:
            case SET_WB_PART:
            case SET_CT_MODE:
            case SHOW_PATTERN:
            case CLOSE_PATTERN:
            case SET_SOUND_MODE:
            case SET_MUTE:
            case SET_ETH_MAC:
            case ENABLE_WIFI:
            case DISABLE_WIFI:
            case SEND_KEY:
            case SHOW_WB_BEFORE:
            case SHOW_WB_AFTER:
            case EXIT_WB:
            case SET_SOUND_BALANCE:
            case FACTORY_SET_WB:
            case FACTORY_WB_PATTERN:
                if (response.arg1 == Types.RESPONSE_OK) {
                    command = RESPONSE_OK;
                } else if (response.arg1 == Types.RESPONSE_ERR) {
                    command = RESPONSE_ERR;
                } else {
                    Log.e(TAG, reqType + " invalid arg1 = " + response.arg1);
                }
                break;

            case GET_WIFI_SCANRESULT:
                command = fromWifiScanResult((List<ScanResult>) response.obj);
                break;

            case GET_SOURCE:
                command = fromInputSource(response.arg1);
                break;

            case GET_CHANNEL:
                command = (response.arg2 == Types.INVALID) ? RESPONSE_ERR : String.valueOf(response.arg2);
                break;

            case GET_VOLUME:
            case GET_BACKLIGHT:
            case GET_WB_PART:
            case FACTORY_GET_WB:
            case GET_USB_STORAGE_CNT:
            case GET_SOUND_BALANCE:
                command = (response.arg1 == Types.INVALID) ? RESPONSE_ERR : String.valueOf(response.arg1);
                break;

            case GET_SPDIF_MODE:
                command = fromSpdifMode(response.arg1);
                break;
	
            case GET_PICTURE_MODE:
                command = fromPictureMode(response.arg1);
                break;

            case GET_SW_VERSION:
            case GET_ETH_IP:
            case GET_BT_VERSION:
            case GET_SERIAL_NUMBER:
                String result = (String) response.obj;
                command = TextUtils.isEmpty(result) ? RESPONSE_ERR : result;
                break;

            case GET_ETH_MAC:
            case GET_WIFI_MAC:
            case GET_BT_MAC:
                String mac = (String) response.obj;
                command = TextUtils.isEmpty(mac) ? RESPONSE_ERR : mac.replace(":", ""); // VS mac without ":"
                break;

            case START_BT_DISCOVERY:
                command = (response.arg1 == Types.RESPONSE_OK) ? "" : RESPONSE_ERR;   // NOTE: DON'T response immediately, will callback to response
                return command; // NOTE: direct return to forbid add END_CHAR

            case GET_BT_DISCOVERIED_DEV:
                command = fromBtDevice((BluetoothDevice) response.obj);
                break;
	
            case GET_CT_MODE:
                command = fromColorTempMode(response.arg1);
                break;
	
            case GET_MUTE:
                command = (response.arg1 != 0) ? "OFF" : "ON";  // on off mean speaker, not mute
                break;

            case START_WIFI_SCAN:
                if (response.arg1 == WIFI_START_RESULT_BUSY) {
                    command = "BUSY";
                } else if (response.arg1 == Types.RESPONSE_OK) {
                    command = RESPONSE_OK;
                } else {
                    command = RESPONSE_ERR;
                }
                break;

            case GET_BT_CONNECTED_DEV:
                command = ((String[]) response.obj).toString();
                break;

            case GET_COMPILE_TIME:
                String compileTime = (String) response.obj;
                command = TextUtils.isEmpty(compileTime) ? RESPONSE_ERR : compileTime;
                break;
            case GET_PROJECT_ID:
            case GET_PANEL_NAME:
                String writeString = (String) response.obj;
                command = TextUtils.isEmpty(writeString) ? RESPONSE_ERR : writeString;
                break;
            case GET_AQ_VERSION:
                String aqVersion = (String) response.obj;
                command = TextUtils.isEmpty(aqVersion) ? RESPONSE_ERR : aqVersion;
                break;
            case GET_PQ_VERSION:
                String pqVersion = (String) response.obj;
                command = TextUtils.isEmpty(pqVersion) ? RESPONSE_ERR : pqVersion;
                break;
            case GET_PANEL_VERSION:
                String panelVerion = (String) response.obj;
                command = TextUtils.isEmpty(panelVerion) ? RESPONSE_ERR : panelVerion;
                break;
            case GET_DATA_VERSION:
                String dataVersion = (String) response.obj;
                command = TextUtils.isEmpty(dataVersion) ? RESPONSE_ERR : dataVersion;
                break;
            case GET_HDCP_1_4:
            case GET_HDCP_2_2:
            case GET_WIDEVINE_STATUS:
            case GET_KEYMASTER_STATUS:
            case GET_PLAYREADY_STATUS:
            case GET_PLAYREADY_2_5_STATUS:
                command = ((boolean)response.obj == true) ? RESPONSE_OK : RESPONSE_ERR;
                break;
				*/
			case WB_PREPARE:
					reply = new byte[11];
					reply[0] = error_replay[0];
					reply[1] = error_replay[1];
					reply[2] = (byte)0x81;
					reply[3] = (byte)response.arg1;
					reply[4] = (byte)0x01;
					reply[5] = (byte)response.arg2;
					reply[6] = (byte)0x00;
					reply[7] = (byte)0x00;
					reply[8] = (byte)0x00;
				    reply[9] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]+(byte)reply[5]+(byte)reply[6]+(byte)reply[7]+(byte)reply[8]) & 0xFF);
					reply[10] = (byte)0x0d;

				break;
		    case WB_CONNECT:
                //command = ((boolean)response.obj == true) ? RESPONSE_OK : RESPONSE_ERR;
                //reply = error_replay;
				//if((boolean)response.obj == true){
				//	reply[3] = 0x01;
				//}

					reply = new byte[11];
					reply[0] = error_replay[0];
					reply[1] = error_replay[1];
					reply[2] = (byte)0x80;
					reply[3] = (byte)0x00;
					reply[4] = (byte)0x00;
					reply[5] = (byte)0x00;
					reply[6] = (byte)0x00;
					reply[7] = (byte)0x00;
					reply[8] = (byte)0x00;
				    reply[9] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]+(byte)reply[5]+(byte)reply[6]+(byte)reply[7]+(byte)reply[8]) & 0xFF);
					reply[10] = (byte)0x0d;
				break;
			case WB_COLORTEMP_OPTION:
				//reply = error_replay;
				//reply[2] = (byte)0x82;
				//if((boolean)response.obj == true){
				//	reply[5] = (byte)response.arg2;
				//}

					reply = new byte[11];
					reply[0] = error_replay[0];
					reply[1] = error_replay[1];
					reply[2] = (byte)0x82;
					reply[3] = (byte)0x00;
					reply[4] = (byte)0x00;
					reply[5] = (byte)response.arg2;
					reply[6] = (byte)0x00;
					reply[7] = (byte)0x00;
					reply[8] = (byte)0x00;
				    reply[9] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]+(byte)reply[5]+(byte)reply[6]+(byte)reply[7]+(byte)reply[8]) & 0xFF);
					reply[10] = (byte)0x0d;
				break;
			case WB_PICTUR_MODE_OPTION:
				reply = error_replay;
				reply[2] = (byte)0x83;
				if((boolean)response.obj == true){
					reply[5] = (byte)response.arg2;
				}
				break;
			case WB_OSD_BACKLIGHT_MAX:
				reply = error_replay;
				reply[2] = (byte)0x84;
				if((boolean)response.obj == true){
					reply[5] = (byte)response.arg2;
				}
				break;
			case WB_OSD_BACKLIGHT_MIN:
				reply = error_replay;
				reply[2] = (byte)0x85;
				if((boolean)response.obj == true){
					reply[5] = (byte)response.arg2;
				}
				break;
			case WB_R_GAIN_SET:
				//reply = error_replay;
				//reply[2] = (byte)0x89;
				//if((boolean)response.obj == true){
				//	reply[3] = (byte)response.arg1;
				//	reply[4] = (byte)response.arg2;
				//	reply[5] = 1;
				//}

					reply = new byte[11];
					reply[0] = error_replay[0];
					reply[1] = error_replay[1];
					reply[2] = (byte)0x89;
					reply[3] = (byte)response.arg1;
					reply[4] = (byte)response.arg2;
					reply[5] = (byte)0x00;
					reply[6] = (byte)0x00;
					reply[7] = (byte)0x00;
					reply[8] = (byte)0x00;
				    reply[9] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]+(byte)reply[5]+(byte)reply[6]+(byte)reply[7]+(byte)reply[8]) & 0xFF);
					reply[10] = (byte)0x0d;
				break;
			case WB_G_GAIN_SET:
				//reply = error_replay;
				//reply[2] = (byte)0x8A;
				//if((boolean)response.obj == true){
				//	reply[3] = (byte)response.arg1;
				//	reply[4] = (byte)response.arg2;
				//	reply[5] = 1;
				//}
					reply = new byte[11];
					reply[0] = error_replay[0];
					reply[1] = error_replay[1];
					reply[2] = (byte)0x8a;
					reply[3] = (byte)0x00;
					reply[4] = (byte)0x00;
					reply[5] = (byte)response.arg1;
					reply[6] = (byte)response.arg2;
					reply[7] = (byte)0x00;
					reply[8] = (byte)0x00;
				    reply[9] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]+(byte)reply[5]+(byte)reply[6]+(byte)reply[7]+(byte)reply[8]) & 0xFF);
					reply[10] = (byte)0x0d;
				break;
			case WB_B_GAIN_SET:
				//reply = error_replay;
				//reply[2] = (byte)0x8B;
				//if((boolean)response.obj == true){
				//	reply[3] = (byte)response.arg1;
				//	reply[4] = (byte)response.arg2;
				//	reply[5] = 1;
				//}
					reply = new byte[11];
					reply[0] = error_replay[0];
					reply[1] = error_replay[1];
					reply[2] = (byte)0x8b;
					reply[3] = (byte)0x00;
					reply[4] = (byte)0x00;
					reply[5] = (byte)0x00;
					reply[6] = (byte)0x00;
					reply[7] = (byte)response.arg1;
					reply[8] = (byte)response.arg2;
				    reply[9] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]+(byte)reply[5]+(byte)reply[6]+(byte)reply[7]+(byte)reply[8]) & 0xFF);
					reply[10] = (byte)0x0d;
				break;
			case WB_STAND_SAVE:
			case WB_WARM_SAVE:
			case WB_COOL_SAVE:
					reply = new byte[11];
					reply[0] = error_replay[0];
					reply[1] = error_replay[1];
					if(response.what == Types.Request_CH.WB_STAND_SAVE.ordinal()){
					    reply[2] = (byte)0x8F;
					} else if(response.what == Types.Request_CH.WB_WARM_SAVE.ordinal()){
					    reply[2] = (byte)0x90;
					} else {
					    reply[2] = (byte)0x91;

					}
					reply[3] = (byte)response.getData().getInt("Rhigh");
					reply[4] = (byte)response.getData().getInt("Rlow");
					reply[5] = (byte)response.getData().getInt("Ghigh");
					reply[6] = (byte)response.getData().getInt("Glow");
					reply[7] = (byte)response.getData().getInt("Bhigh");
					reply[8] = (byte)response.getData().getInt("Blow");
				    reply[9] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]+(byte)reply[5]+(byte)reply[6]+(byte)reply[7]+(byte)reply[8]) & 0xFF);
					reply[10] = (byte)0x0d;
					break;

			case WB_R_GAIN_GET:
				reply = error_replay;
				reply[2] = (byte)0x92;
				if((boolean)response.obj == true){
					reply[3] = (byte)response.arg1;
					reply[4] = (byte)response.arg2;
					reply[5] = 1;
				}
				break;
			case WB_G_GAIN_GET:
				reply = error_replay;
				reply[2] = (byte)0x93;
				if((boolean)response.obj == true){
					reply[3] = (byte)response.arg1;
					reply[4] = (byte)response.arg2;
					reply[5] = 1;
				}
				break;
			case WB_B_GAIN_GET:
				reply = error_replay;
				reply[2] = (byte)0x94;
				if((boolean)response.obj == true){
					reply[3] = (byte)response.arg1;
					reply[4] = (byte)response.arg2;
					reply[5] = 1;
				}
				break;
			case CONNECT:
				reply = error_replay;
				if((boolean)response.obj == true){
					reply[2] = 0x00;
					reply[4] = 0x01;
				}
				reply[5] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]) & 0xFF);
				break;
			case ARC_CEC_OPT:
				reply = error_replay;
				if((boolean)response.obj == true){
					reply[2] = 0x10;
					reply[3] =(byte)response.arg1;
					reply[4] =(byte)response.arg2;
				}
				reply[5] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]) & 0xFF);
				break;
			case KPORT_OFF:
				reply = error_replay;
				if((boolean)response.obj == true){
					reply[2] = 0x11;
					reply[3] =(byte)response.arg1;
					reply[4] = 0x00;
				}
				reply[5] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]) & 0xFF);
				break;
			case GET_KEYCODE:
				reply = error_replay;
				if((boolean)response.obj == true){
					reply[2] = 0x12;
					reply[3] = 0x00;//(byte)response.arg1;
					reply[4] = 0x00;
				}
				reply[5] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]) & 0xFF);
				break;
			case KPORT_ON:
				reply = error_replay;
				if((boolean)response.obj == true){
					reply[2] = 0x13;
					reply[3] =(byte)response.arg1;
					reply[4] = 0x00;
				}
				reply[5] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]) & 0xFF);
				break;
			case GET_LAN_IP:
				String ip = (String)response.obj;
				Log.d(TAG,"ip "+ip);
				byte[]ipByte = new byte[7];
				try{

				ipByte = ip.getBytes("US-ASCII");
				} catch (Exception e){
					e.printStackTrace();

				}
				Log.d(TAG,"ipByte "+ipByte+" length "+ipByte.length);
				reply = new byte[ipByte.length+6];
				reply[0] = (byte)0x36;
				reply[1] = (byte)0x86;
				reply[2] = (byte)0x20;
				reply[3] = (byte)0x01;
				for(int i = 4; i < 4 +ipByte.length; i++){
					reply[i] = ipByte[i-4];
				}
				byte ipSum = 0;
				for(int i = 0; i < (reply.length -2); i++){
					Log.d(TAG,"before reply["+i+"]= "+reply[i]+"\n");
                    ipSum = (byte)((byte)ipSum+ (byte)reply[i]);
					Log.d(TAG,"after reply["+i+"]= "+reply[i]+"\n");
				}
				reply[reply.length -2] = (byte)(ipSum & 0xFF);
				reply[reply.length-1] = (byte)0x0d;
				break;
			case WIFI_SCAN:
				reply = error_replay;
				reply[2] = 0x21;
				if(response.arg1 == Types.RESPONSE_OK){
					reply[4] = (byte)0x01;
				} else {
					reply[4] = (byte)0x00;
				}
				reply[5] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]) & 0xFF);
				break;
			case PRESET_CHANNEL:
				reply = error_replay;
				reply[2] = 0x22;
				reply[3] = (byte)response.arg1;
				reply[4] = (byte)(response.arg2 == 0 ? 1 :0);
				reply[5] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]) & 0xFF);
				break;
			case BT_SCAN:
				reply = error_replay;
				reply[2] = 0x23;
				reply[4] = (byte)response.arg1;
				reply[5] = (byte)((byte)(reply[0]+(byte)reply[1]+(byte)reply[2]+(byte)reply[3]+(byte)reply[4]) & 0xFF);
				break;
			case GET_VER_INFO:
				String ver = (String)response.obj;
				Log.d(TAG,"ver "+ver);
				byte[]verByte = new byte[7];
				try{

				verByte = ver.getBytes("US-ASCII");
				} catch (Exception e){
					e.printStackTrace();

				}
				Log.d(TAG,"verByte "+verByte+" length "+verByte.length);
				reply = new byte[verByte.length+6];
				reply[0] = (byte)0x36;
				reply[1] = (byte)0x86;
				reply[2] = (byte)0x2A;
				reply[3] = (byte)response.arg1;
				for(int i = 4; i < 4 +verByte.length; i++){
					reply[i] = verByte[i-4];
				}
				byte verSum = 0;
				for(int i = 0; i < (reply.length -2); i++){
					Log.d(TAG,"before reply["+i+"]= "+reply[i]+"\n");
                    verSum = (byte)((byte)verSum+ (byte)reply[i]);
					Log.d(TAG,"after reply["+i+"]= "+reply[i]+"\n");
				}
				reply[reply.length -2] = (byte)(verSum & 0xFF);
				reply[reply.length-1] = (byte)0x0d;
				break;




            default:
                Log.e(TAG, "unkown respons type = " + reqType);
                //command = RESPONSE_ERR;
                break;
        }
                Log.e(TAG, " reply = " + reply +" error_replay "+error_replay);
				return reply;//error_replay;

        //return command + END_CHAR;
    }

    /***************** function. ****************/
    private void setPowerRequest(String param, Message request) {
        if (param.equals(PARAM_0000)) {
            request.what = Types.Request.POWER_OFF.ordinal();
        } else {
            request.what = Types.INVALID;
        }
    }

    private void setStandbyRequest(String param, Message request) {
        if (param.equals(PARAM_0000)) {
            request.what = Types.Request.STANDBY.ordinal();
        } else {
            request.what = Types.INVALID;
        }
    }

    private void setSourceRequest(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_SOURCE.ordinal();
        } else {
            int source = toInputSource(param);
            if (source != Types.INVALID) {
                request.what = Types.Request.SET_SOURCE.ordinal();
                request.arg1 = source;
            } else {
                request.what = Types.INVALID;
            }
        }
    }

    private void setChannelRequest(boolean isAtv, String param, Message request) {
        Types.ChannelType type = isAtv ? Types.ChannelType.ATV : Types.ChannelType.DTV;
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_CHANNEL.ordinal();
            request.arg1 = type.ordinal();
        } else {
            try {
                request.what = Types.Request.SET_CHANNEL.ordinal();
                request.arg1 = type.ordinal();
                request.arg2 = Integer.valueOf(param);
            } catch (NumberFormatException e) {
                Log.e(TAG, "invalid channel number = " + param);
                request.what = Types.INVALID;
            }
        }
    }

    private void setVolumeRequest(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_VOLUME.ordinal();
        } else {
            try {
                Log.d(TAG, "setVolumeRequest: " + param);
                request.what = Types.Request.SET_VOLUME.ordinal();
                request.arg1 = Integer.valueOf(param);
            } catch (NumberFormatException e) {
                Log.e(TAG, "invalid volume = " + param);
                request.what = Types.INVALID;
            }
        }
    }

    private void setSpdifModeRequest(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_SPDIF_MODE.ordinal();
        } else {
            int mode = toSpdifMode(param);
            if (mode != Types.INVALID) {
                request.what = Types.Request.SET_SPDIF_MODE.ordinal();
                request.arg1 = toSpdifMode(param);
            } else {
                request.what = Types.INVALID;
            }
        }
    }

    private void setSendKeyRequest(String command, Message request) {
        int code = toKeyCode(command);
        if (code != Types.INVALID) {
            request.what = Types.Request.SEND_KEY.ordinal();
            request.arg1 = code;
        } else {
            Log.e(TAG, "invalid key = " + command);
            request.what = Types.INVALID;
        }
    }

    private void setFactoryWbRequest(String cmd, String param, Message request) {
        try {
            int ctMode = toColorTempMode(cmd.substring(2, 3));
            if (ctMode == Types.INVALID) {
                request.what = Types.INVALID;
                return;
            }

            String part = cmd.substring(3, 4);
            Types.ColorPart colorPart;
            if (part.equals("R")) {
                colorPart = Types.ColorPart.RED;
            } else if (part.equals("G")) {
                colorPart = Types.ColorPart.GREEN;
            } else if (part.equals("B")) {
                colorPart = Types.ColorPart.BLUE;
            } else {
                request.what = Types.INVALID;
                return;
            }

            request.arg1 = ctMode;
            request.arg2 = colorPart.ordinal();
            if (param.equals(PARAM_INQUIRE)) {
                request.what = Types.Request.FACTORY_GET_WB.ordinal();
            } else {
                request.what = Types.Request.FACTORY_SET_WB.ordinal();
                request.obj = Integer.valueOf(param);
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
            request.what = Types.INVALID;
        }
    }

    private void setPictureMode(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_PICTURE_MODE.ordinal();
        } else {
            request.what = Types.Request.SET_PICTURE_MODE.ordinal();
            request.arg1 = toPictureMode(param);
        }
    }

    private boolean setEnterFactoryMode(String param, Message request, String command) {

        boolean success = false;

        String subCmd = command.substring(0, 4);


        //if Active mode, do nothing
        if (getFactoryMode() == Types.FactoryMode.STATE_ACTIVE.ordinal()
            && !subCmd.equals(CMD_FACTORY_MENU)) {
            return success;
        }

        if ((subCmd.equals(CMD_M_MODE))
                && (param.equals(PARAM_0001)
                && (getFactoryMode() == Types.FactoryMode.STATE_INIT.ordinal()))) {
            setFactoryMode(Types.FactoryMode.STATE_READY.ordinal());
            request.what = Types.Request.DIRECT_RESPONSE.ordinal();
            request.obj = RESPONSE_OK;
            Log.d(TAG, "setEnterFactoryMode: " + getFactoryMode());
            success = true;
        } else if ((subCmd.equals(CMD_F_MODE_ENABLE))
                && (param.equals(PARAM_ENABLE_F_MODE)
                && (getFactoryMode() == Types.FactoryMode.STATE_READY.ordinal()))) {
            setFactoryMode(Types.FactoryMode.STATE_DISACTIVE.ordinal());
            request.what = Types.Request.DIRECT_RESPONSE.ordinal();
            request.obj = RESPONSE_OK;
            Log.d(TAG, "setEnterFactoryMode: " + getFactoryMode());

            success = true;
        } else if (subCmd.equals(CMD_FACTORY_MENU)
                && param.equals(PARAM_0000)
                && (getFactoryMode() == Types.FactoryMode.STATE_DISACTIVE.ordinal())) {
            //Active
            setFactoryMode(Types.FactoryMode.STATE_ACTIVE.ordinal());
            request.what = Types.Request.DIRECT_RESPONSE.ordinal();
            request.obj = RESPONSE_OK;
            Log.d(TAG, "setEnterFactoryMode: " + getFactoryMode());
            success = true;
        } else if (subCmd.equals(CMD_FACTORY_MENU)
                && param.equals(PARAM_0001)
                && (getFactoryMode() == Types.FactoryMode.STATE_ACTIVE.ordinal())) {
            setFactoryMode(Types.FactoryMode.STATE_DISACTIVE.ordinal());
            request.what = Types.Request.DIRECT_RESPONSE.ordinal();
            request.obj = RESPONSE_OK;
            Log.d(TAG, "setEnterFactoryMode: " + getFactoryMode());

            success = true;
        } else { //handle error
            request.what = Types.Request.DIRECT_RESPONSE.ordinal();
            request.obj = RESPONSE_ERR;
            Log.d(TAG, "setEnterFactoryMode: " + getFactoryMode());
            success = true;
        }

        return success;
    }

    private void setFactoryModeMenu(String param, Message request) {
        if (param.equals(PARAM_0000)) {         //Enter Factory Menu
            Log.d(TAG, "setFactoryMode: Enter factory menu");
            request.what = Types.Request.ENTER_FACTORY_MENU.ordinal();
        } else if (param.equals(PARAM_0001)) {      //Exit Factory Menu
            Log.d(TAG, "setFactoryMode: Exit factory menu");
            request.what = Types.Request.EXIT_FACTORY_MENU.ordinal();
        }
    }

    private void setFactoryInspectionMode(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            Log.d(TAG, "setFactoryInspectionMode: Get factory inspection mode");
            request.what = Types.Request.ENTER_FACTORY_MODE.ordinal();
        }
    }

    private void setFactoryInit(String param, Message request) {
        if (param.equals(PARAM_FACTORY_INIT)) {
            request.what = Types.Request.FACTORY_INIT.ordinal();
            request.arg1 = Types.RESPONSE_OK;
        }
    }

    private void setBacklight(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_BACKLIGHT.ordinal();
        } else {
            try {
                request.what = Types.Request.SET_BACKLIGHT.ordinal();
                request.arg1 = Integer.valueOf(param);
            } catch (NumberFormatException e) {
                Log.e(TAG, "invalid backlight = " + param);
                request.what = Types.INVALID;
            }
        }
    }

    private void setTactSwTest(String param, Message request) {
        if (param.equals(PARAM_0000)) {
            Log.d(TAG, "setTactSwTest: Keycheck ON");
            request.what = Types.Request.DIRECT_RESPONSE.ordinal();
            request.obj = KEYCHECK_ON;
            mIsKeyCheckOn = true;
        } else if (param.equals(PARAM_0001)) {
            Log.d(TAG, "setTactSwTest: Keycheck Off");
            request.what = Types.Request.DIRECT_RESPONSE.ordinal();
            request.obj = KEYCHECK_OFF;
            mIsKeyCheckOn = false;
        }
    }

    private void getSwVersion(String param, Message request) {
        if (param.equals(PARAM_0001)) {
            request.what = Types.Request.GET_SW_VERSION.ordinal();
        } else {
            Log.d(TAG, "getSwVersion: Invalid Param[" + param + "]");
        }
    }

    private void setWbAdjust(String param, Message request) {
        if (param.equals(PARAM_0000)) {
            request.what = Types.Request.RESET_WB.ordinal();
        } else if (param.equals(PARAM_WB_ADJUST_EXIT)) {
            request.what = Types.Request.EXIT_WB.ordinal();
        }
    }

    private void setWbAdjR(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_WB_PART.ordinal();
            request.arg1 = Types.ColorPart.RED.ordinal();
        } else {
            request.what = Types.Request.SET_WB_PART.ordinal();
            request.arg1 = Types.ColorPart.RED.ordinal();
            try {
                request.arg2 = Integer.valueOf(param);
            } catch (NumberFormatException e) {
                Log.e(TAG, "Invalid Red Value[" + param + "]");
                request.what = Types.INVALID;
            }

        }
    }

    private void setWbAdjG(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_WB_PART.ordinal();
            request.arg1 = Types.ColorPart.GREEN.ordinal();
        } else {
            request.what = Types.Request.SET_WB_PART.ordinal();
            request.arg1 = Types.ColorPart.GREEN.ordinal();
            try {
                request.arg2 = Integer.valueOf(param);
            } catch (NumberFormatException e) {
                Log.e(TAG, "Invalid Green Value[" + param + "]");
                request.what = Types.INVALID;
            }

        }
    }

    private void setWbAdjB(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_WB_PART.ordinal();
            request.arg1 = Types.ColorPart.BLUE.ordinal();
        } else {
            request.what = Types.Request.SET_WB_PART.ordinal();
            request.arg1 = Types.ColorPart.BLUE.ordinal();
            try {
                request.arg2 = Integer.valueOf(param);
            } catch (NumberFormatException e) {
                Log.e(TAG, "Invalid Blue Value[" + param + "]");
                request.what = Types.INVALID;
            }
        }
    }

    private void setColorTempMode(String param, Message request) {
        if (param.equals(PARAM_COLORTEMP_INQUIRE)) {
            request.what = Types.Request.GET_CT_MODE.ordinal();
        } else {
            int mode = toColorTempMode(param);
            if (mode == Types.INVALID) {
                Log.e(TAG, "unknown ct mode = " + mode);
                request.what = Types.INVALID;
            } else {
                request.what = Types.Request.SET_CT_MODE.ordinal();
                request.arg1 = mode;
            }
        }
    }

    private void showWbPatternMax(String param, Message request) {
        if (param.equals(PARAM_WB_MAX_BEFORE)) {
            request.what = Types.Request.SHOW_WB_BEFORE.ordinal();
        } else if (param.equals(PARAM_WB_MAX_AFTER)) {
            request.what = Types.Request.SHOW_WB_AFTER.ordinal();
        }
    }

    private void setLcdPatternDisplay(String param, Message request) {
        if (param.equals(PARAM_PATTERN_OFF)) {
            request.what = Types.Request.CLOSE_PATTERN.ordinal();
        } else {
            try {

                int color = toColor(param);
                if (color == Types.INVALID) {
                    request.what = Types.INVALID;
                } else {
                    request.what = Types.Request.SHOW_PATTERN.ordinal();
                    request.arg1 = color;
                }
            } catch (NumberFormatException e) {
                Log.e(TAG, "Invalid Pattern" + param);
                request.what = Types.INVALID;
            }
        }
    }

    private void factoryWbPattern(String param, Message request) {
        try {
            request.what = Types.Request.FACTORY_WB_PATTERN.ordinal();
            request.arg1 = Integer.valueOf(param.substring(1, 4));
            request.arg2 = Integer.valueOf(param.substring(0, 1));
        } catch (NumberFormatException e) {
            Log.e(TAG, "Invalid Pattern" + param);
            request.what = Types.INVALID;
        }
    }

    private void SoundBalanceTest(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_SOUND_BALANCE.ordinal();
        } else {
            request.what = Types.Request.SET_SOUND_BALANCE.ordinal();
            try {
                request.arg1 = Integer.valueOf(param);
            } catch (NumberFormatException e) {
                Log.e(TAG, "Invalid Sound Balance Value" + param);
                request.what = Types.INVALID;
            }
        }
    }

    private void SpeakerTest(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_MUTE.ordinal();
        } else {
            request.what = Types.Request.SET_MUTE.ordinal();
            try {
                request.arg1 = Integer.valueOf(param);
            } catch (NumberFormatException e) {
                Log.e(TAG, "Invalid speaker status" + param);
                request.what = Types.INVALID;
            }
        }
    }

    private void getUsbCount(String param, Message request) {
        if (param.equals(PARAM_0000)) {
            request.what = Types.Request.GET_USB_STORAGE_CNT.ordinal();
        }
    }

    private void ethernetMacAddress(String param, Message request, String command) {
        if (param.equals(PARAM_ETH_MAC_READ)) {
            request.what = Types.Request.GET_ETH_MAC.ordinal();
        } else {
            if (!getEthernetWMode()) {
                request.what = Types.Request.DIRECT_RESPONSE.ordinal();
                request.obj = RESPONSE_OK;
                setEthernetWMode(true);
            } else {
                request.what = Types.Request.SET_ETH_MAC.ordinal();
                request.obj = command;
                setEthernetWMode(false);
            }
        }
    }

    private void wifiSettings(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_WIFI_MAC.ordinal();
        } else if (param.equals(PARAM_0001)) {
            request.what = Types.Request.ENABLE_WIFI.ordinal();
        } else if (param.equals(PARAM_0000)) {
            request.what = Types.Request.DISABLE_WIFI.ordinal();
        } else if (param.equals(PARAM_WIFI_SCAN)) {
            request.what = Types.Request.START_WIFI_SCAN.ordinal();
        } else if (param.startsWith(PARAM_WIFI_AP_SSID_PREFIX)) {
            mApSsid = VS_AP_SSID_PREFIX + param.substring(2);
            Log.d(TAG, "set WIFI AP to " + mApSsid);
            request.what = Types.Request.DIRECT_RESPONSE.ordinal();
            request.obj = RESPONSE_OK;
        } else if (param.startsWith(PARAM_WIFI_THRESHOLD_RSSI_PREFIX)) {
            try {
                mThresholdRssi = Integer.valueOf(param.substring(1));
                Log.d(TAG, "set WIFI RSSI to " + mThresholdRssi);
                request.what = Types.Request.DIRECT_RESPONSE.ordinal();
                request.obj = RESPONSE_OK;
            } catch (NumberFormatException e) {
                e.printStackTrace();
                request.what = Types.INVALID;
            }
        } else if (param.equals(PARAM_WIFI_CMP_RSSI)) {
            request.what = Types.Request.GET_WIFI_SCANRESULT.ordinal();
        } else {
            Log.e(TAG, "unkown wifi param = " + param);
            request.what = Types.INVALID;
        }
    }

    private void bluetoothSettings(String param, Message request) {
        if (param.equals(PARAM_BT_MAC)) {
            request.what = Types.Request.GET_BT_MAC.ordinal();
        } else if (param.startsWith(PARAM_BT_AP_PREFIX)) {
            mBtAp = VS_BT_AP_PREFIX + param.substring(2);
            Log.d(TAG, "set BT AP to " + mBtAp);
            request.what = Types.Request.DIRECT_RESPONSE.ordinal();
            request.obj = RESPONSE_OK;
        } else if (param.equals(PARAM_BT_SCAN_CMP)) {
            request.what = Types.Request.START_BT_DISCOVERY.ordinal();
            request.obj = mBtAp;
        } else {
            mBtAp = param;
            Log.d(TAG, "set BT AP to " + mBtAp);
            request.what = Types.Request.START_BT_DISCOVERY.ordinal();
            request.obj = mBtAp;
        }
    }

    private void getEthernetIP(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_ETH_IP.ordinal();
        }
    }

    private void getSN(String param, Message request) {
        if (param.equals(PARAM_INQUIRE)) {
            request.what = Types.Request.GET_SERIAL_NUMBER.ordinal();
        }
    }

    private void getStatus(String param, Message request) {
        if (param.equals(PARAM_GETCOMPILETIME)) {
            getCompileTime(param, request);
        } else if (param.equals(PARAM_GETPROJECTID)) {
            getProjectID(param, request);
        } else if (param.equals(PARAM_GETAQVER)) {
            getAqVersion(param, request);
        } else if (param.equals(PARAM_GETPQVER)) {
            getPqVersion(param, request);
        } else if (param.equals(PARAM_GETHDCPKEY14)) {
            getHdcpKey14(param, request);
        } else if (param.equals(PARAM_GETHDCPKEY22)) {
            getHdcpKey22(param, request);
        } else if (param.equals(PARAM_GETKEYMASTER)) {
            getKeyMaster(param, request);
        } else if (param.equals(PARAM_GETPANELSEL)) {
            getPanelName(param, request);
        } else if (param.equals(PARAM_GETWIDEVINEKEY)) {
            getWideVineKey(param, request);
        } else if (param.equals(PARAM_GETPLAYREADY)) {
            getPlayReady(param, request);
        } else if (param.equals(PARAM_GETPLAYREADY25)) {
            getPlayReady25(param, request);
        } else if (param.equals(PARAM_GETPANELVERSION)) {
            getPanelVersion(param, request);
        } else if (param.equals(PARAM_GETDATAVERSION)) {
            getDataVersion(param, request);
        }
    }

    private void getCompileTime(String param, Message request) {

        request.what = Types.Request.GET_COMPILE_TIME.ordinal();
    }

    private void getProjectID(String param, Message request) {

        request.what = Types.Request.GET_PROJECT_ID.ordinal();
    }
    private void getAqVersion(String param, Message request) {
        request.what = Types.Request.GET_AQ_VERSION.ordinal();
    }
    private void getPqVersion(String param, Message request) {
        request.what = Types.Request.GET_PQ_VERSION.ordinal();
    }

    private void getPanelVersion(String param, Message request) {
        request.what = Types.Request.GET_PANEL_VERSION.ordinal();
    }

    private void getDataVersion(String param, Message request) {
        request.what = Types.Request.GET_DATA_VERSION.ordinal();
    }

    private void getHdcpKey14(String param, Message request) {

        request.what = Types.Request.GET_HDCP_1_4.ordinal();
    }

    private void getHdcpKey22(String param, Message request) {

        request.what = Types.Request.GET_HDCP_2_2.ordinal();
    }

    private void getKeyMaster(String param, Message request) {

        request.what = Types.Request.GET_KEYMASTER_STATUS.ordinal();
    }

    private void getPanelName(String param, Message request) {

        request.what = Types.Request.GET_PANEL_NAME.ordinal();
    }

    private void getWideVineKey(String param, Message request) {
        request.what = Types.Request.GET_WIDEVINE_STATUS.ordinal();
    }

    private void getPlayReady(String param, Message request) {

        request.what = Types.Request.GET_PLAYREADY_STATUS.ordinal();
    }

    private void getPlayReady25(String param, Message request) {

        request.what = Types.Request.GET_PLAYREADY_2_5_STATUS.ordinal();
    }

    /*************** data type convert. **********/

    // input source
    private static final Types.InputSource[] mSourceMap = { // indexed by SOURCE_XXX
            Types.InputSource.OTHER,    // invalid
            Types.InputSource.HDMI,
            Types.InputSource.HDMI2,
            Types.InputSource.HDMI3,
            Types.InputSource.HDMI4,
            Types.InputSource.DTV,
            Types.InputSource.ATV,
            Types.InputSource.CVBS };

    private static final int toInputSource(String param) {
        int source = Types.INVALID;
        try {
            int value = Integer.valueOf(param);
            int index = value / 1000;
            if (value % 1000 == 0 &&  index >= SOURCE_HDMI1 && index <= SOURCE_AV) {
                source = mSourceMap[index].ordinal();
            }
        } catch (NumberFormatException e) {
            Log.e(TAG, "invalid input source = " + param);
        }

        return source;
    }

    private static final String fromInputSource(int source) {
        for (int i = 1; i < mSourceMap.length; i++) {
            if (mSourceMap[i].ordinal() == source) {
                return String.valueOf(i);
            }
        }

        return RESPONSE_ERR;
    }

    // spdif mode
    private static final Types.SpdifMode[] mSpdifModeMap = {    // indexed by SPDIF_MODE_XXX
            Types.SpdifMode.AUTO,
            Types.SpdifMode.BYPASS,
            Types.SpdifMode.PCM };

    private static final int toSpdifMode(String param) {
        int mode = Types.INVALID;
        try {
            int value = Integer.valueOf(param);
            if (value >= 0 && value <= 2) {
                mode = mSpdifModeMap[value].ordinal();
            }
        } catch (NumberFormatException e) {
            Log.e(TAG, "invalid spdif mode = " + param);
        }

        return mode;
    }

    private static final String fromSpdifMode(int mode) {
        for (int i = 0; i < mSpdifModeMap.length; i++) {
            if (mSpdifModeMap[i].ordinal() == mode) {
                return String.valueOf(i);
            }
        }

        return RESPONSE_ERR;
    }

    // picture mode
    private static final Types.PictureMode[] mPicModeMap = {    // indexed by PICTURE_MODE_XXX
            Types.PictureMode.STANDARD, // invalid
            Types.PictureMode.USER,
            Types.PictureMode.STANDARD,
            Types.PictureMode.VIVID,
            Types.PictureMode.SPORT,
            Types.PictureMode.MOVIE,
            Types.PictureMode.GAME,
            Types.PictureMode.ENERGY_SAVING };

    private static final int toPictureMode(String param) {
        int mode = Types.INVALID;
        try {
            int value = Integer.valueOf(param);
            int index = value / 1000;
            if (value % 1000 == 0 &&  index >= PICTURE_MODE_USER && index <= PICTURE_MODE_ENERGYSAVE) {
                mode = mPicModeMap[index].ordinal();
            }
        } catch (NumberFormatException e) {
            Log.e(TAG, "invalid picture mode = " + param);
        }

        return mode;
    }

    private static final String fromPictureMode(int mode) {
        for (int i = 1; i < mPicModeMap.length; i++) {
            if (mPicModeMap[i].ordinal() == mode) {
                return String.valueOf(i);
            }
        }

        return RESPONSE_ERR;
    }

    // color temperature
    private static final Types.ColorTempMode[] mCtModeMap = {   // indexed by CT_MODE_XXX
            Types.ColorTempMode.STANDARD,   // invalid
            Types.ColorTempMode.STANDARD,
            Types.ColorTempMode.COOL,
            Types.ColorTempMode.WARM,
            Types.ColorTempMode.USER };

    private static final int toColorTempMode(String param) {
        int mode = Types.INVALID;
        try {
            int index = Integer.valueOf(param);
            if (index >= CT_MODE_NORMAL && index <= CT_MODE_USER) {
                mode = mCtModeMap[index].ordinal();
            } else {
                Log.e(TAG, "unsupported ct mode index = " + index);
            }
        } catch (NumberFormatException e) {
            Log.e(TAG, "invalid color temperature mode = " + param);
        }

        return mode;
    }

    private static final String fromColorTempMode(int mode) {
        for (int i = 1; i < mCtModeMap.length; i++) {
            if (mCtModeMap[i].ordinal() == mode) {
                return String.valueOf(i);
            }
        }
        return RESPONSE_ERR;
    }

    // keys
    private static final int toKeyCode(String command) {
        int code = Types.INVALID;
        switch (command) {
            case KEY_VOL_UP:
                code = KeyEvent.KEYCODE_VOLUME_UP;
                break;

            case KEY_VOL_DOWN:
                code = KeyEvent.KEYCODE_VOLUME_DOWN;
                break;

            case KEY_CHANNEL_UP:
                code = KeyEvent.KEYCODE_CHANNEL_UP;
                break;

            case KEY_CHANNEL_DOWN:
                code = KeyEvent.KEYCODE_CHANNEL_DOWN;
                break;

            case KEY_INPUT:
                code = KeyEvent.KEYCODE_TV_INPUT;
                break;

            case KEY_MENU:
                code = KeyEvent.KEYCODE_MENU;
                break;

            case KEY_POWER:
                code = KeyEvent.KEYCODE_POWER;
                break;

            default:
                Log.e(TAG, "invalid key = " + command);
        }

        return code;
    }

    private static final int[] mColorMap = {    // indexed VS color
            Types.INVALID,  // invalid
            0xFF0000,   // red
            0x00FF00,   // green
            0x0000FF,   // blue
            0xFFFFFF,   // white
            0x808080,   // white - 50%
            0x000000,   // black
    };

    private static int toColor(String param) {
        int index = Integer.valueOf(param);
        if (index > 0 && index < mColorMap.length) {
            return mColorMap[index];
        } else {
            return Types.INVALID;
        }
    }

    private String fromWifiScanResult(List<ScanResult> results) {
        String command = "";

        if (mApSsid.isEmpty()) {    // empty for test
            command = RESPONSE_OK + " : ";
            for (ScanResult r : results) {
                command += r.SSID + "(" + r.level + ") ";
            }
        } else {
            command = RESPONSE_ERR;
            for (ScanResult r : results) {
                if (r.SSID.equals(mApSsid)) {
                    command = ((r.level >= mThresholdRssi) ? RESPONSE_OK : RESPONSE_ERR) + "(" + r.level + ")";
                    break;
                }
            }
        }

        return command;
    }

    private String fromBtDevice(BluetoothDevice bt) {
        String name = (bt != null && bt.getName() != null) ? bt.getName() : "";
        if (mBtAp.isEmpty()) {  // empty for test
            return name;
        } else {
            return name.contains(mBtAp) ? RESPONSE_OK : RESPONSE_ERR;
        }
    }

    private boolean getEthernetWMode() {
        return mEthernetWMode;
    }

    private void setEthernetWMode(boolean write) {
        mEthernetWMode = write;
    }

    public static int getFactoryMode() {
        return mFactoryMode;
    }

    public static void setFactoryMode(int FactoryMode) {
        mFactoryMode = FactoryMode;
    }
}
